﻿#if NETFX || NETCORE

using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;

namespace Apewer.Surface
{

    /// <summary></summary>
    public class BlockBox : BaseControl
    {

        #region definition

        private const int StateNormal = 1;
        private const int StateHover = 2;
        private const int StateLost = 3;

        private Color _normalborder, _normalwall, _hoverborder, _hoverwall, _lostborder, _lostwall;
        private int _state = StateNormal;
        private bool _disposed = false;
        private bool _haveborder = true;



        //private Bitmap _background = null;

        private void VarInit()
        {
            _normalborder = FormsUtility.GraceBorder;
            _normalwall = FormsUtility.White;
            _hoverborder = FormsUtility.GraceSilver;
            _hoverwall = FormsUtility.White;
        }

        #endregion

        #region this

        /// <summary></summary>
        public BlockBox()
        {
            VarInit();

            SetStyle(ControlStyles.UserPaint, true);
            SetStyle(ControlStyles.AllPaintingInWmPaint, true);
            SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
            // SetStyle(ControlStyles.ResizeRedraw, value);
            SetStyle(ControlStyles.DoubleBuffer, true);
            UpdateStyles();

            //this.BackColor = normalborder;
            this.Padding = new Padding(1);

            //this.Controls.Add(_body);

            EventInit();
            UpdateColor();
        }

        /// <summary></summary>
        public new void Dispose()
        {
            if (!_disposed)
            {
                _disposed = true;
                base.Dispose();
            }
        }

        #endregion

        #region public accessor

        /// <summary>添加子控件。</summary>
        public void Add(Control control)
        {
            if (control != null) this.Controls.Add(control);
        }

        /// <summary>移除所有子控件。</summary>
        public void Clean()
        {
            this.Controls.Clear();
        }

        /// <summary>移除所有子控件。</summary>
        public void Clear()
        {
            this.Controls.Clear();
        }

        /// <summary>子控件的数量。</summary>
        public int Count
        {
            get { return this.Controls.Count; }
        }

        /// <summary>获取子控件。</summary>
        /// <param name="index">子控件索引。</param>
        public Control this[int index]
        {
            get { return this.Controls[index]; }
        }

        /// <summary></summary>
        public bool HaveBorder
        {
            get { return _haveborder; }
            set { _haveborder = value; UpdateColor(); }
        }

        /// <summary></summary>
        public Color NormalBorder
        {
            get { return _normalborder; }
            set { _normalborder = value; if (_state == StateNormal) UpdateColor(); }
        }

        /// <summary></summary>
        public Color NormalWall
        {
            get { return _normalwall; }
            set { _normalwall = value; if (_state == StateNormal) UpdateColor(); }
        }

        /// <summary></summary>
        public Color HoverBorder
        {
            get { return _hoverborder; }
            set { _hoverborder = value; if (_state == StateHover) UpdateColor(); }
        }

        /// <summary></summary>
        public Color HoverWall
        {
            get { return _hoverwall; }
            set { _hoverwall = value; if (_state == StateHover) UpdateColor(); }
        }

        /// <summary></summary>
        public Color LostBorder
        {
            get { return _lostborder; }
            set { _lostborder = value; if (_state == StateLost) UpdateColor(); }
        }

        /// <summary></summary>
        public Color LostWall
        {
            get { return _lostwall; }
            set { _lostwall = value; if (_state == StateLost) UpdateColor(); }
        }

        /// <summary></summary>
        public void GoHover()
        {
            if (_state != StateHover)
            {
                _state = StateHover;
                UpdateColor();
            }
        }

        /// <summary></summary>
        public void GoNormal()
        {
            if (_state != StateNormal)
            {
                _state = StateNormal;
                UpdateColor();
            }
        }

        /// <summary></summary>
        public void GoLost()
        {
            if (_state != StateLost)
            {
                _state = StateLost;
                UpdateColor();
            }
        }

        #endregion

        #region private method

        private void UpdateColor()
        {
            if ((this.Width > 0) && (this.Height > 0))
            {
                Color vbordercolor;
                Color vwallcolor;
                switch (_state)
                {
                    default:
                    case StateNormal:
                        vbordercolor = NormalBorder;
                        vwallcolor = NormalWall;
                        break;
                    case StateHover:
                        vbordercolor = HoverBorder;
                        vwallcolor = HoverWall;
                        break;
                    case StateLost:
                        vbordercolor = LostBorder;
                        vwallcolor = LostWall;
                        break;
                }

                var vbackground = new Bitmap(this.Width, this.Height);
                var vgraphics = Graphics.FromImage(vbackground);
                var vpen = new Pen(vbordercolor);
                vgraphics.SmoothingMode = SmoothingMode.None;
                vgraphics.CompositingMode = CompositingMode.SourceCopy;
                vgraphics.Clear(vwallcolor);
                vgraphics.DrawRectangle(vpen, 0, 0, this.Width - 1, this.Height - 1);
                vpen.Dispose();
                vgraphics.Dispose();
                if (this.BackgroundImage != null)
                {
                    this.BackgroundImage.Dispose();
                    this.BackgroundImage = null;
                }
                this.BackgroundImage = vbackground;
            }
        }

        #endregion

        #region private event 

        private void EventInit()
        {
            //_body.MouseClick += event_caption_mouseclick;
            //_body.MouseDoubleClick += event_caption_mousedoubleclick;
            //_body.MouseDown += event_caption_mousedown;
            //_body.MouseUp += event_caption_mouseup;
            //_body.MouseMove += event_caption_mousemove;
            //_body.MouseWheel += event_caption_mousewheel;

            //_body.Click += event_click;
            //_body.DoubleClick += event_doubleclick;
            //_body.MouseCaptureChanged += event_caption_mousecapturechanged;
            //_body.MouseEnter += event_caption_mouseenter;
            //_body.MouseHover += event_caption_mousehover;
            //_body.MouseLeave += event_caption_mouseleave;

            //_body.PreviewKeyDown += event_previewkeydown;

            this.Resize += Event_This_Resize;
        }

        private void Event_This_Resize(object sender, EventArgs e)
        {
            UpdateColor();
        }

        private void Event_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
        {
            this.OnPreviewKeyDown(e);
        }

        private void Event_DoubleClick(object sender, EventArgs e)
        {
            this.OnDoubleClick(e);
        }

        private void Event_Click(object sender, EventArgs e)
        {
            this.OnClick(e);
        }

        private void Event_Caption_MouseWheel(object sender, MouseEventArgs e)
        {
            int voffset = HaveBorder ? 1 : 0;
            this.OnMouseWheel(new MouseEventArgs(e.Button, e.Clicks, e.X + voffset, e.Y + voffset, e.Delta));
        }

        private void Event_Caption_MouseMove(object sender, MouseEventArgs e)
        {
            int voffset = HaveBorder ? 1 : 0;
            this.OnMouseMove(new MouseEventArgs(e.Button, e.Clicks, e.X + voffset, e.Y + voffset, e.Delta));
        }

        private void Event_Caption_MouseLeave(object sender, EventArgs e)
        {
            this.OnMouseLeave(e);
        }

        private void Event_Caption_MouseHover(object sender, EventArgs e)
        {
            this.OnMouseHover(e);
        }

        private void Event_Caption_MouseEnter(object sender, EventArgs e)
        {
            this.OnMouseEnter(e);
        }

        private void Event_Caption_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            int voffset = HaveBorder ? 1 : 0;
            this.OnMouseDoubleClick(new MouseEventArgs(e.Button, e.Clicks, e.X + voffset, e.Y + voffset, e.Delta));
        }

        private void Event_Caption_MouseCaptureChanged(object sender, EventArgs e)
        {
            this.OnMouseCaptureChanged(e);
        }

        private void Event_Caption_MouseUp(object sender, MouseEventArgs e)
        {
            int voffset = HaveBorder ? 1 : 0;
            this.OnMouseUp(new MouseEventArgs(e.Button, e.Clicks, e.X + voffset, e.Y + voffset, e.Delta));
        }

        private void Event_Caption_MouseClick(object sender, MouseEventArgs e)
        {
            int voffset = HaveBorder ? 1 : 0;
            this.OnMouseClick(new MouseEventArgs(e.Button, e.Clicks, e.X + voffset, e.Y + voffset, e.Delta));
        }

        private void Event_Caption_MouseDown(object sender, MouseEventArgs e)
        {
            int voffset = HaveBorder ? 1 : 0;
            this.OnMouseDown(new MouseEventArgs(e.Button, e.Clicks, e.X + voffset, e.Y + voffset, e.Delta));
        }

        #endregion

        #region common

        /// <summary>鼠标滚轮事件。</summary>
        public new void WheelMouse(MouseEventArgs e)
        {
            OnMouseWheel(e);
        }

        #endregion

    }
}

#endif
